<template>
  <div class="websocket-client">
    <div class="header">
      <h1>WebSocket 客户端</h1>
      <div class="connection-status" :class="connectionStatus">
        <span class="status-indicator"></span>
        {{ statusText }}
      </div>
    </div>

    <div class="connection-controls">
      <el-input 
        v-model="wsUrl" 
        placeholder="输入 WebSocket 地址"
        class="url-input"
      />
      <el-button 
        @click="toggleConnection" 
        :loading="isConnecting"
        :type="isConnected ? 'danger' : 'primary'"
      >
        {{ isConnected ? '断开连接' : '连接' }}
      </el-button>
    </div>

    <div class="message-area">
      <div class="message-list" ref="messageList">
        <div v-for="(msg, index) in messages" :key="index" class="message-item">
          <div class="message-meta">
            <span class="sender">{{ msg.sender }}</span>
            <span class="time">{{ formatTime(msg.timestamp) }}</span>
          </div>
          <div class="message-content" :class="msg.type">
            {{ msg.content }}
          </div>
        </div>
      </div>

      <div class="message-input" v-if="isConnected">
        <el-input 
          v-model="messageContent" 
          placeholder="输入消息内容..." 
          @keyup.enter="sendMessage"
          class="input-field"
        />
        <el-button @click="sendMessage" type="primary">发送</el-button>
      </div>
    </div>

    <div class="reconnect-settings" v-if="!isConnected">
      <el-checkbox v-model="autoReconnect" class="auto-reconnect">自动重连</el-checkbox>
      <el-input-number 
        v-model="reconnectInterval" 
        :min="1" 
        :max="60" 
        label="重连间隔(秒)"
        class="reconnect-interval"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, onUnmounted, nextTick } from 'vue';
import { ElInput, ElButton, ElCheckbox, ElInputNumber } from 'element-plus';

// WebSocket 连接状态
const wsUrl = ref('ws://1.92.74.42:8087/socket');
const isConnected = ref(false);
const isConnecting = ref(false);
const connectionStatus = ref('disconnected');
const statusText = ref('未连接');
const webSocket = ref(null);
const messages = ref([]);
const messageContent = ref('');

// 重连设置
const autoReconnect = ref(true);
const reconnectInterval = ref(5);
let reconnectTimer = null;

// 格式化时间显示
const formatTime = (timestamp) => {
  return new Date(timestamp).toLocaleTimeString();
};

// 连接/断开 WebSocket
const toggleConnection = () => {
  if (isConnected.value) {
    disconnect();
  } else {
    connect();
  }
};

// 建立连接
const connect = () => {
  if (isConnecting.value || isConnected.value) return;

  isConnecting.value = true;
  updateStatus('connecting', '连接中...');

  try {
    webSocket.value = new WebSocket(wsUrl.value);

    // 连接成功
    webSocket.value.onopen = () => {
      isConnected.value = true;
      isConnecting.value = false;
      updateStatus('connected', '已连接');
      addMessage('系统', 'WebSocket 连接成功', 'system');
      
      // 清除重连定时器
      if (reconnectTimer) {
        clearTimeout(reconnectTimer);
        reconnectTimer = null;
      }
    };

    // 接收消息
    webSocket.value.onmessage = (event) => {
      console.log(JSON.parse(event.data));
      try {
        // 尝试解析 JSON 格式消息
        const data = JSON.parse(event.data);

        addMessage('服务器', data.content || event.data, 'received');
      } catch (e) {
        // 非 JSON 格式消息
        addMessage('服务器', event.data, 'received');
      }
    };

    // 连接关闭
    webSocket.value.onclose = (event) => {
      isConnected.value = false;
      isConnecting.value = false;
      
      const reason = event.code === 1000 ? '正常关闭' : `错误码: ${event.code}`;
      updateStatus('disconnected', `已断开 (${reason})`);
      addMessage('系统', `连接已关闭: ${reason}`, 'system');

      // 自动重连
      if (autoReconnect.value) {
        scheduleReconnect();
      }
    };

    // 连接错误
    webSocket.value.onerror = (error) => {
      isConnecting.value = false;
      updateStatus('error', '连接错误');
      addMessage('系统', `连接错误: ${error.message || '未知错误'}`, 'error');
    };
  } catch (error) {
    isConnecting.value = false;
    updateStatus('error', '连接失败');
    addMessage('系统', `连接失败: ${error.message}`, 'error');
  }
};

// 断开连接
const disconnect = () => {
  if (webSocket.value) {
    webSocket.value.close(1000, '用户主动断开');
    webSocket.value = null;
  }
  
  // 清除重连定时器
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
    reconnectTimer = null;
  }
};

// 发送消息
const sendMessage = () => {
  if (!isConnected.value || !messageContent.value.trim()) return;

  const message = messageContent.value.trim();
  try {
    webSocket.value.send(message);
    addMessage('我', message, 'sent');
    messageContent.value = '';
  } catch (error) {
    addMessage('系统', `发送失败: ${error.message}`, 'error');
  }
};

// 添加消息到列表
const addMessage = (sender, content, type) => {
  messages.value.push({
    sender,
    content,
    type,
    timestamp: new Date()
  });
  
  // 滚动到最新消息
  nextTick(() => {
    const messageList = document.querySelector('.message-list');
    if (messageList) {
      messageList.scrollTop = messageList.scrollHeight;
    }
  });
};

// 更新连接状态
const updateStatus = (status, text) => {
  connectionStatus.value = status;
  statusText.value = text;
};

// 安排重连
const scheduleReconnect = () => {
  if (reconnectTimer) clearTimeout(reconnectTimer);
  
  addMessage('系统', `将在 ${reconnectInterval.value} 秒后尝试重连...`, 'system');
  
  reconnectTimer = setTimeout(() => {
    if (!isConnected.value && autoReconnect.value) {
      connect();
    }
  }, reconnectInterval.value * 1000);
};

// 监听自动重连设置变化
watch(autoReconnect, (newVal) => {
  if (newVal && !isConnected.value) {
    scheduleReconnect();
  } else if (reconnectTimer) {
    clearTimeout(reconnectTimer);
    reconnectTimer = null;
  }
});

// 组件卸载时清理
onUnmounted(() => {
  disconnect();
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
  }
});

// 初始化
onMounted(() => {
  // 可以在这里设置默认连接
  // connect();
});
</script>

<style scoped>
.websocket-client {
  max-width: 800px;
  margin: 20px auto;
  padding: 20px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #f0f0f0;
}

.header h1 {
  margin: 0;
  font-size: 24px;
  color: #1f2329;
}

.connection-status {
  display: flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 14px;
  font-weight: 500;
}

.status-indicator {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
}

.connection-status.connected {
  background-color: #f0fdf4;
  color: #166534;
}

.connection-status.connected .status-indicator {
  background-color: #22c55e;
}

.connection-status.connecting {
  background-color: #fef3c7;
  color: #92400e;
}

.connection-status.connecting .status-indicator {
  background-color: #f59e0b;
}

.connection-status.disconnected {
  background-color: #fef2f2;
  color: #b91c1c;
}

.connection-status.disconnected .status-indicator {
  background-color: #ef4444;
}

.connection-status.error {
  background-color: #fee2e2;
  color: #dc2626;
}

.connection-status.error .status-indicator {
  background-color: #dc2626;
}

.connection-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.url-input {
  flex: 1;
}

.message-area {
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  overflow: hidden;
}

.message-list {
  height: 400px;
  overflow-y: auto;
  padding: 15px;
  background-color: #fafafa;
}

.message-item {
  margin-bottom: 15px;
  padding-bottom: 15px;
  border-bottom: 1px solid #f0f0f0;
}

.message-item:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.message-meta {
  display: flex;
  justify-content: space-between;
  margin-bottom: 5px;
  font-size: 12px;
}

.sender {
  font-weight: 600;
}

.time {
  color: #9ca3af;
}

.message-content {
  padding: 8px 12px;
  border-radius: 4px;
  line-height: 1.5;
}

.message-content.sent {
  background-color: #e6f7ff;
  color: #1890ff;
  text-align: right;
}

.message-content.received {
  background-color: #f0f9eb;
  color: #52c41a;
}

.message-content.system {
  background-color: #f9fafb;
  color: #6b7280;
}

.message-content.error {
  background-color: #fee2e2;
  color: #dc2626;
}

.message-input {
  display: flex;
  gap: 10px;
  padding: 10px;
  background-color: #f9fafb;
  border-top: 1px solid #e5e7eb;
}

.input-field {
  flex: 1;
}

.reconnect-settings {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px dashed #e5e7eb;
  font-size: 14px;
}

.auto-reconnect {
  display: flex;
  align-items: center;
}

.reconnect-interval {
  width: 180px !important;
}
</style>
